/**
 * 演员跟随路径类
 */

 import * as THREE from "./three.js/build/three.module.js";

 class A3Flow {

  currentPos = 0;
  pathPoint = new THREE.Vector3();
  pathQuaternion = new THREE.Quaternion();

  // 跟随方式
  // 绝对控制: 从路径获取点的位姿信息，更新到物理引擎；
  // 速度控制: 从路径获取目标点位姿信息，根据当前演员位姿，计算速度值；
  // 力控:未实现**
  method = "velocity"; // ["absolute", "velocity", "force"]
  timeStep = .05; // 这个数值时表现较好

  constructor( actor, path, step=0.001 ) {

    this.actor = actor;
    this.path = path;
    this.step = step;

    this.updateActor(0);
  }

  updateActor( pos = 0 ) {
    // 设置演员至路径起点
    this.actor.setPosition( this.path.getPointAt( pos ) );
    this.actor.setQuaternion( this.path.getQuaternionAt( pos ));

    this.currentPos = pos;
  }

  updateVelocity( pos=0 ) {

    const pointA = this.actor.position;// this.path.getPointAt( pos );
    const pointB = this.path.getPointAt( pos );

    const quatA = this.actor.quaternion.clone();
    const quatB = this.path.getQuaternionAt( pos );
    const euler = new THREE.Euler().setFromQuaternion( quatA.invert().multiply(quatB) );
    
    const av = new THREE.Vector3( euler.x, euler.y, euler.z );
    
    pointB.sub(pointA).divideScalar( this.timeStep );
    av.divideScalar( this.timeStep );

    this.actor.setLinearVelocity( pointB );
    this.actor.setAngularVelocity( av );

    this.currentPos = pos;
    
  }


  update( ) {

    switch( this.method ) {
      case "absolute":
        this.updateActor( (this.currentPos + this.step) < 1 ? (this.currentPos + this.step) : 0 );
        break;
      case "velocity":
        this.updateVelocity( (this.currentPos + this.step) < 1 ? (this.currentPos + this.step) : 0 );
        break;
      default:
        this.updateActor( (this.currentPos + this.step) < 1 ? (this.currentPos + this.step) : 0 );
        break;
    }

  }

 }

 export default A3Flow;